import { onUnmounted, nextTick, Ref } from "vue";

/**
 * 自动滚动处理函数
 * @param option 配置选项
 * @param option.outerDom 外部容器DOM引用
 * @param option.innerDom 内部容器DOM引用
 */
export default function autoScroll(option: {
  outerDom: Ref<HTMLElement | null>;
  innerDom: Ref<HTMLElement | null>;
}) {
  const { outerDom, innerDom } = option;

  // 定义类型
  let outerHeight: number = 0;
  let innerHeight: number = 0;
  let scrollDistance: number = 0;
  let delayTimer: ReturnType<typeof setTimeout> | null = null;
  let currentPosition = 0;
  let isScrolling = true;
  let innerElement: HTMLElement | null = null;
  let outerElement: HTMLElement | null = null;
  let animationFrameId: number | null = null;
  let animate: () => void = () => { };

  /**
   * 设置自动滚动
   */
  function setAutoScroll() {
    innerElement = innerDom.value || null;
    outerElement = outerDom.value || null;

    if (!innerElement || !outerElement) return;

    nextTick(() => {
      // 获取外部容器和内部容器的高度
      outerHeight = getStyle(outerElement!, 'height');
      innerHeight = getStyle(innerElement!, 'height');

      // 计算需要滚动的距离
      scrollDistance = innerHeight - outerHeight;

      // 如果内部容器高度小于外部容器高度，则不需要滚动
      if (scrollDistance <= 0) return;

      const fps = (1 / 60).toFixed(2); // 每秒刷新60次
      innerElement!.style.transition = `transform ${fps}s linear`;

      // 动画函数
      animate = () => {
        // 停止之前的动画 - 在重新开始 - 避免回调函数重复执行
        if (animationFrameId) {
          cancelAnimationFrame(animationFrameId);
        }

        if (isScrolling) {
          currentPosition += 0.4; // 向上滚动速度
          innerElement!.style.transform = `translate3d(0, -${currentPosition}px, 0)`;

          if (currentPosition >= scrollDistance) {
            currentPosition = 0;
            innerElement!.style.transition = '';
            isScrolling = false;

            if (delayTimer) {
              clearTimeout(delayTimer);
            }

            delayTimer = setTimeout(() => {
              isScrolling = true;
              innerElement!.style.transform = `translate3d(0, 0, 0)`;
              animationFrameId = requestAnimationFrame(animate);
              if (delayTimer) {
                clearTimeout(delayTimer);
                delayTimer = null;
              }
            }, 1500);
          }
        }

        animationFrameId = requestAnimationFrame(animate);
      };

      // 开始动画
      animationFrameId = requestAnimationFrame(animate);
      // 绑定事件
      bindEvent();
    });
  }

  /**
   * 鼠标移入事件处理
   */
  const mouseenterFunc = () => {
    isScrolling = false;
  };

  /**
   * 鼠标移出事件处理
   */
  const mouseleaveFunc = () => {
    isScrolling = true;
    if (animate) {
      animate();
    }
  };

  /**
   * 绑定鼠标事件
   */
  function bindEvent() {
    if (innerElement) {
      innerElement.addEventListener('mouseenter', mouseenterFunc);
      innerElement.addEventListener('mouseleave', mouseleaveFunc);
    }
  }

  /**
   * 组件卸载时清理资源
   */
  onUnmounted(() => {
    if (innerElement) {
      innerElement.removeEventListener('mouseenter', mouseenterFunc);
      innerElement.removeEventListener('mouseleave', mouseleaveFunc);
    }

    if (delayTimer) {
      clearTimeout(delayTimer);
      delayTimer = null;
    }

    if (animationFrameId) {
      cancelAnimationFrame(animationFrameId);
      animationFrameId = null;
    }
  });

  return [setAutoScroll];
}

/**
 * 获取元素样式值
 * @param el 元素对象
 * @param attr 样式属性名
 * @returns 样式值的数值部分
 */
function getStyle(el: HTMLElement, attr: string): number {
  return parseFloat(window.getComputedStyle(el, null)[attr]);
}